package player
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import geometry.IGeobject;
	import geometry.Polyline;
	import geometry.algorithms.GeobjectClassifier;
	import geometry.util.Vector2d;
	
	import mx.core.UIComponent;
	
	public class BoardView extends UIComponent
	{
		public var MODE_AUTO:int = 1;
		public var MODE_MODIFY:int = 2;
		public var MODE_MANUAL:int = 3;
		
		[Bindable] public var lineColor:Number = 0x000000;
		[Bindable] public var lineThickness:int = 3;
		[Bindable] public var mode:int = MODE_AUTO;
		
		
		// --------------------------------------------------------------------------------------------
		public function BoardView()
		{
			_model = new Array();
			this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    	this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
		}
		
		// --------------------------------------------------------------------------------------------
	  public function clear():void{
	  	
	  	while(_model.length > 0){
	  		removeChild(_model.pop().sprite);
 			}
	  }


	  // --------------------------------------------------------------------------------------------
    private function onMouseDown(e:MouseEvent):void
    {
    	if( mode == MODE_MODIFY ){
    	}
    	else{
	    	_sprite = new Sprite();
	    	_strokes = new Array();
	    	
	    	_sprite.graphics.lineStyle(1, 0xaaaaaa);
	    	this.addChild(_sprite);
	    	_sprite.graphics.moveTo(mouseX, mouseY);
	    	_strokes.push( new Point(mouseX, mouseY) );
	    	
	    	this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
	    } 
    } 

	  // --------------------------------------------------------------------------------------------
    private function onMouseMove(e:MouseEvent):void 
    {
    	if( _strokes ){
    		_sprite.graphics.lineTo(mouseX, mouseY);
    		_strokes.push( new Point(mouseX, mouseY) );
    	}
    	else if( mode == MODE_MODIFY ){
    		markVertex(mouseX, mouseY);
    	}
    }
        
	  // --------------------------------------------------------------------------------------------
    private function onMouseUp(e:MouseEvent):void 
    {    	
    	var geobject:IGeobject = null;

			if( mode == MODE_AUTO ){
	    	var classifier : GeobjectClassifier = new GeobjectClassifier();
	    	geobject = classifier.classify(_strokes);
	    	removeChild(_sprite);
	  	}
	  	else if( mode == MODE_MODIFY ){
	  		
	  	}
	  	else{
				geobject = new Polyline(_strokes);	  		
				removeChild(_sprite);
	  	}
	  	
	  	if( geobject != null ){
	  		addGeobject(geobject);
	  	}
	  	
	  	_strokes = null;
    }
        
	  // --------------------------------------------------------------------------------------------
    override protected function updateDisplayList(w:Number, h:Number):void
    {
    	var g:Graphics = this.graphics;
    	
    	g.clear();
    	g.beginFill(_bgColor, 1);
      g.drawRect(0, 0, unscaledWidth, unscaledHeight);
      g.endFill();
        
    }

	  // --------------------------------------------------------------------------------------------
		private function addGeobject(geobject : IGeobject):void{

  		var view: GeobjectView = new GeobjectView(geobject);
  		view.setLineStyle(lineThickness, lineColor);
  		_model.push(view);
  		addChild(view.sprite);
		}
		
	  // --------------------------------------------------------------------------------------------
		private function markVertex( x:Number, y:Number ) : void{
			
			var point : Point = null;
			var input : Point = new Point(x, y);
			
			// Find vertex
			for each( var view : GeobjectView in _model ){
				for each (var p : Point in view.geobject.points){
					var v : Vector2d = Vector2d.points2Vector(input, p);
					
					if( v.length < 10 ){
						point = p;
						break;				
					} 
				}
			}
			
			showMarker( point );
		}
		
		// --------------------------------------------------------------------------------------------
		private function showMarker( pos : Point ) : void{

			if(_marker){
				removeChild(_marker);
			}
			
			if( pos ){
				_marker = new Sprite();
				_marker.graphics.lineStyle(1, 0xff0000);
				_marker.graphics.drawCircle(pos.x, pos.y, 10);
				addChild(_marker);
			}
			else{
				_marker = null;
			}
					
		}
		
		
		// --------------------------------------------------------------------------------------------
		// Private members
		/** List of all object */
		private var _model : Array;
		private var _sprite : Sprite;
		private var _strokes: Array;
		private var _marker : Sprite;
		/** Style */ 
		private var _bgColor : Number = 0xffffff;

	}
}